home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / patch12.zip / UTIL.C < prev    next >
C/C++ Source or Header  |  1990-05-30  |  8KB  |  365 lines

  1. #include "EXTERN.h"
  2. #include "common.h"
  3. #include "INTERN.h"
  4. #include "util.h"
  5.  
  6. /* Rename a file, copying it if necessary. */
  7.  
  8. int
  9. move_file(from,to)
  10. char *from, *to;
  11. {
  12.     char bakname[512];
  13.     Reg1 char *s;
  14.     Reg2 int i;
  15.     Reg3 int fromfd;
  16.  
  17.     /* to stdout? */
  18.  
  19.     if (strEQ(to, "-")) {
  20. #ifdef DEBUGGING
  21.     if (debug & 4)
  22.         say2("Moving %s to stdout.\n", from);
  23. #endif
  24.     fromfd = open(from, 0);
  25.     if (fromfd < 0)
  26.         fatal2("patch: internal error, can't reopen %s\n", from);
  27.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  28.         if (write(1, buf, i) != 1)
  29.         fatal1("patch: write failed\n");
  30.     Close(fromfd);
  31.     return 0;
  32.     }
  33.  
  34.     if (origprae) {
  35.         Strcpy (bakname, origprae);
  36.         Strcat(bakname, to);
  37.     } else {
  38.            Strcpy(bakname, to);
  39.         Strcat(bakname, origext?origext:ORIGEXT);
  40.     }
  41.     if (stat(to, &filestat) >= 0) {    /* output file exists */
  42.     dev_t to_device = filestat.st_dev;
  43.     ino_t to_inode  = filestat.st_ino;
  44.     char *simplename = bakname;
  45.     
  46.     for (s=bakname; *s; s++) {
  47.         if (*s == '/')
  48.         simplename = s+1;
  49.     }
  50.     /* find a backup name that is not the same file */
  51.     while (stat(bakname, &filestat) >= 0 &&
  52.         to_device == filestat.st_dev && to_inode == filestat.st_ino) {
  53.         for (s=simplename; *s && !islower(*s); s++) ;
  54.         if (*s)
  55.         *s = toupper(*s);
  56.         else
  57.         Strcpy(simplename, simplename+1);
  58.     }
  59.     while (unlink(bakname) >= 0) ;    /* while() is for benefit of Eunice */
  60. #ifdef DEBUGGING
  61.     if (debug & 4)
  62.         say3("Moving %s to %s.\n", to, bakname);
  63. #endif
  64.     if (link(to, bakname) < 0) {
  65.         say3("patch: can't backup %s, output is in %s\n",
  66.         to, from);
  67.         return -1;
  68.     }
  69.     while (unlink(to) >= 0) ;
  70.     }
  71. #ifdef DEBUGGING
  72.     if (debug & 4)
  73.     say3("Moving %s to %s.\n", from, to);
  74. #endif
  75.     if (link(from, to) < 0) {        /* different file system? */
  76.     Reg4 int tofd;
  77.     
  78.     tofd = creat(to, 0666);
  79.     if (tofd < 0) {
  80.         say3("patch: can't create %s, output is in %s.\n",
  81.           to, from);
  82.         return -1;
  83.     }
  84.     fromfd = open(from, 0);
  85.     if (fromfd < 0)
  86.         fatal2("patch: internal error, can't reopen %s\n", from);
  87.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  88.         if (write(tofd, buf, i) != i)
  89.         fatal1("patch: write failed\n");
  90.     Close(fromfd);
  91.     Close(tofd);
  92.     }
  93.     Unlink(from);
  94.     return 0;
  95. }
  96.  
  97. /* Copy a file. */
  98.  
  99. void
  100. copy_file(from,to)
  101. char *from, *to;
  102. {
  103.     Reg3 int tofd;
  104.     Reg2 int fromfd;
  105.     Reg1 int i;
  106.     
  107.     tofd = creat(to, 0666);
  108.     if (tofd < 0)
  109.     fatal2("patch: can't create %s.\n", to);
  110.     fromfd = open(from, 0);
  111.     if (fromfd < 0)
  112.     fatal2("patch: internal error, can't reopen %s\n", from);
  113.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  114.     if (write(tofd, buf, i) != i)
  115.         fatal2("patch: write (%s) failed\n", to);
  116.     Close(fromfd);
  117.     Close(tofd);
  118. }
  119.  
  120. /* Allocate a unique area for a string. */
  121.  
  122. char *
  123. savestr(s)
  124. Reg1 char *s;
  125. {
  126.     Reg3 char *rv;
  127.     Reg2 char *t;
  128.  
  129.     if (!s)
  130.     s = "Oops";
  131.     t = s;
  132.     while (*t++);
  133.     rv = malloc((MEM) (t - s));
  134.     if (rv == Nullch) {
  135.     if (using_plan_a)
  136.         out_of_mem = TRUE;
  137.     else
  138.         fatal1("patch: out of memory (savestr)\n");
  139.     }
  140.     else {
  141.     t = rv;
  142.     while (*t++ = *s++);
  143.     }
  144.     return rv;
  145. }
  146.  
  147. #if defined(lint) && defined(CANVARARG)
  148.  
  149. /*VARARGS ARGSUSED*/
  150. say(pat) char *pat; { ; }
  151. /*VARARGS ARGSUSED*/
  152. fatal(pat) char *pat; { ; }
  153. /*VARARGS ARGSUSED*/
  154. ask(pat) char *pat; { ; }
  155.  
  156. #else
  157.  
  158. /* Vanilla terminal output (buffered). */
  159.  
  160. void
  161. say(pat,arg1,arg2,arg3)
  162. char *pat;
  163. long arg1,arg2,arg3;
  164. {
  165.     fprintf(stderr, pat, arg1, arg2, arg3);
  166.     Fflush(stderr);
  167. }
  168.  
  169. /* Terminal output, pun intended. */
  170.  
  171. void                /* very void */
  172. fatal(pat,arg1,arg2,arg3)
  173. char *pat;
  174. long arg1,arg2,arg3;
  175. {
  176.     void my_exit();
  177.  
  178.     say(pat, arg1, arg2, arg3);
  179.     my_exit(1);
  180. }
  181.  
  182. /* Get a response from the user, somehow or other. */
  183.  
  184. void
  185. ask(pat,arg1,arg2,arg3)
  186. char *pat;
  187. long arg1,arg2,arg3;
  188. {
  189.     int ttyfd;
  190.     int r;
  191.     bool tty2 = isatty(2);
  192.  
  193.     Sprintf(buf, pat, arg1, arg2, arg3);
  194.     Fflush(stderr);
  195.     write(2, buf, strlen(buf));
  196.     if (tty2) {                /* might be redirected to a file */
  197.     r = read(2, buf, sizeof buf);
  198.     }
  199.     else if (isatty(1)) {        /* this may be new file output */
  200.     Fflush(stdout);
  201.     write(1, buf, strlen(buf));
  202.     r = read(1, buf, sizeof buf);
  203.     }
  204.     else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
  205.                     /* might be deleted or unwriteable */
  206.     write(ttyfd, buf, strlen(buf));
  207.     r = read(ttyfd, buf, sizeof buf);
  208.     Close(ttyfd);
  209.     }
  210.     else if (isatty(0)) {        /* this is probably patch input */
  211.     Fflush(stdin);
  212.     write(0, buf, strlen(buf));
  213.     r = read(0, buf, sizeof buf);
  214.     }
  215.     else {                /* no terminal at all--default it */
  216.     buf[0] = '\n';
  217.     r = 1;
  218.     }
  219.     if (r <= 0)
  220.     buf[0] = 0;
  221.     else
  222.     buf[r] = '\0';
  223.     if (!tty2)
  224.     say1(buf);
  225. }
  226. #endif /* lint */
  227.  
  228. /* How to handle certain events when not in a critical region. */
  229.  
  230. void
  231. set_signals(reset)
  232. int reset;
  233. {
  234.     void my_exit();
  235. #ifndef lint
  236. #ifdef VOIDSIG
  237.     static void (*hupval)(),(*intval)();
  238. #else
  239.     static int (*hupval)(),(*intval)();
  240. #endif
  241.  
  242.     if (!reset) {
  243.     hupval = signal(SIGHUP, SIG_IGN);
  244.     if (hupval != SIG_IGN)
  245. #ifdef VOIDSIG
  246.         hupval = my_exit;
  247. #else
  248.         hupval = (int(*)())my_exit;
  249. #endif
  250.     intval = signal(SIGINT, SIG_IGN);
  251.     if (intval != SIG_IGN)
  252. #ifdef VOIDSIG
  253.         intval = my_exit;
  254. #else
  255.         intval = (int(*)())my_exit;
  256. #endif
  257.     }
  258.     Signal(SIGHUP, hupval);
  259.     Signal(SIGINT, intval);
  260. #endif
  261. }
  262.  
  263. /* How to handle certain events when in a critical region. */
  264.  
  265. void
  266. ignore_signals()
  267. {
  268. #ifndef lint
  269.     Signal(SIGHUP, SIG_IGN);
  270.     Signal(SIGINT, SIG_IGN);
  271. #endif
  272. }
  273.  
  274. /* Make sure we'll have the directories to create a file. */
  275.  
  276. void
  277. makedirs(filename,striplast)
  278. Reg1 char *filename;
  279. bool striplast;
  280. {
  281.     char tmpbuf[256];
  282.     Reg2 char *s = tmpbuf;
  283.     char *dirv[20];
  284.     Reg3 int i;
  285.     Reg4 int dirvp = 0;
  286.  
  287.     while (*filename) {
  288.     if (*filename == '/') {
  289.         filename++;
  290.         dirv[dirvp++] = s;
  291.         *s++ = '\0';
  292.     }
  293.     else {
  294.         *s++ = *filename++;
  295.     }
  296.     }
  297.     *s = '\0';
  298.     dirv[dirvp] = s;
  299.     if (striplast)
  300.     dirvp--;
  301.     if (dirvp < 0)
  302.     return;
  303.     strcpy(buf, "mkdir");
  304.     s = buf;
  305.     for (i=0; i<=dirvp; i++) {
  306.     while (*s) s++;
  307.     *s++ = ' ';
  308.     strcpy(s, tmpbuf);
  309.     *dirv[i] = '/';
  310.     }
  311.     system(buf);
  312. }
  313.  
  314. /* Make filenames more reasonable. */
  315.  
  316. char *
  317. fetchname(at,strip_leading,assume_exists)
  318. char *at;
  319. int strip_leading;
  320. int assume_exists;
  321. {
  322.     char *s;
  323.     char *name;
  324.     Reg1 char *t;
  325.     char tmpbuf[200];
  326.  
  327.     if (!at)
  328.     return Nullch;
  329.     s = savestr(at);
  330.     for (t=s; isspace(*t); t++) ;
  331.     name = t;
  332. #ifdef DEBUGGING
  333.     if (debug & 128)
  334.     say4("fetchname %s %d %d\n",name,strip_leading,assume_exists);
  335. #endif
  336.     if (strnEQ(name, "/dev/null", 9))    /* so files can be created by diffing */
  337.     return Nullch;            /*   against /dev/null. */
  338.     for (; *t && !isspace(*t); t++)
  339.     if (*t == '/')
  340.         if (--strip_leading >= 0)
  341.         name = t+1;
  342.     *t = '\0';
  343.     if (name != s && *s != '/') {
  344.     name[-1] = '\0';
  345.     if (stat(s, &filestat) && filestat.st_mode & S_IFDIR) {
  346.         name[-1] = '/';
  347.         name=s;
  348.     }
  349.     }
  350.     name = savestr(name);
  351.     Sprintf(tmpbuf, "RCS/%s", name);
  352.     free(s);
  353.     if (stat(name, &filestat) < 0 && !assume_exists) {
  354.     Strcat(tmpbuf, RCSSUFFIX);
  355.     if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+4, &filestat) < 0) {
  356.         Sprintf(tmpbuf, "SCCS/%s%s", SCCSPREFIX, name);
  357.         if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+5, &filestat) < 0) {
  358.         free(name);
  359.         name = Nullch;
  360.         }
  361.     }
  362.     }
  363.     return name;
  364. }
  365.